

/*
  TikTok Captcha Final Decryption Hook Script
  Target: javax.crypto.Cipher
  Strategy: Hook the lowest level of decryption to bypass reflection or other obfuscation.
*/

console.log("Script loaded. Waiting for Java to be ready...");

Java.perform(function() {
    console.log("Java VM is ready. Attaching to Cipher and AESEncrypt...");

    // --- Strategy 1: Hook the AESEncrypt.decrypt method directly (for verification) ---
    try {
        const AESEncrypt = Java.use('com.heytap.msp.push.encrypt.AESEncrypt');
        AESEncrypt.decrypt.implementation = function(key, encrypted_data) {
            console.log("================ [ AESEncrypt.decrypt Called! ] ================");
            console.log("[+] Key: " + key);
            console.log("[+] Encrypted Input: " + encrypted_data);
            
            // Call original method to get the decrypted data
            const decrypted = this.decrypt(key, encrypted_data);
            
            console.log("[+] Decrypted Result (Plaintext):\n" + decrypted);
            console.log("====================================================================");
            
            return decrypted;
        };
        console.log("[+] Hook on com.heytap.msp.push.encrypt.AESEncrypt.decrypt is set.");
    } catch (e) {
        console.error("[-] Failed to hook AESEncrypt.decrypt. It might be obfuscated or not used directly.", e);
    }

    // --- Strategy 2: Hook the core Cipher class (The Ultimate Hook) ---
    try {
        const Cipher = Java.use('javax.crypto.Cipher');
        
        // Hooking doFinal(byte[])
        Cipher.doFinal.overload('[B').implementation = function(data) {
            // In decryption mode, 'data' is the ciphertext.
            // In encryption mode, 'data' is the plaintext.
            const result = this.doFinal(data);
            
            // Check if we are in DECRYPT_MODE (2)
            if (this.opmode.value === 2) {
                console.log("================ [ Cipher.doFinal DECRYPTING ] ================");
                try {
                    // Attempt to convert the decrypted result (byte array) to a UTF-8 string
                    const plaintext = Java.use('java.lang.String').$new(result, 'UTF-8');
                    console.log("[+] Decrypted Data (Plaintext):\n" + plaintext);
                } catch (e) {
                    console.log("[+] Decrypted Data (Could not convert to String, printing bytes):");
                    console.log(result);
                }
                console.log("=================================================================");
            }
            
            return result;
        };

        console.log("[+] Hook on javax.crypto.Cipher.doFinal is set.");

    } catch (e) {
        console.error("[-] Failed to hook Cipher.doFinal.", e);
    }

    console.log("\nAll hooks are in place. Please trigger the captcha in the app.");
});
